package com.fingard.dsp.bank.directbank.bony02;


import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.*;
import java.util.Date;

public class BONY02SinglePay extends BONY02Base implements ISinglePay {

    /**
     * 单笔支付
     *
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);//返回ats对象
        RetAtsSglDetail tmpRetDetail;
        tmpRetDetail = externalPayments(p_req1908);
        if ("-1".equals(tmpRetDetail.respCode) && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    private RetAtsSglDetail externalPayments(ReqSingle p_req1908) throws Exception {
        //通用参数
        transCode = "DealTransfer";
        busiDate = Format.Date8Format.format(new Date());
        seqNo = p_req1908.reqHeader.transSeqID;
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail = bankTransfer(p_req1908, tmpRetDetail);
        return tmpRetDetail;
    }

    private RetAtsSglDetail bankTransfer(ReqSingle p_req1908, RetAtsSglDetail retDetail) throws Exception {
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter);
        xmlWriter.writeStartElement("body");
        XElement tmpXElement = new XElement("entity", "");
        tmpXElement.addChild(new XElement("billCode", p_req1908.singleDetail.askNumber));//付款单号
        tmpXElement.addChild(new XElement("payerAccount", p_req1908.singleDetail.payAct));//付款人账号
        tmpXElement.addChild(new XElement("payerName", p_req1908.singleDetail.payName));//付款人名称
        tmpXElement.addChild(new XElement("payerBank", p_req1908.singleDetail.payBankLocation));//付款方开户行
        tmpXElement.addChild(new XElement("receiveAccount", p_req1908.singleDetail.recAct));//收款人账号
        tmpXElement.addChild(new XElement("receiveName", p_req1908.singleDetail.recName));//收款人名称
        tmpXElement.addChild(new XElement("receiveBank", p_req1908.singleDetail.recBankLocation));//收款方开户行
        tmpXElement.addChild(new XElement("depositCode", p_req1908.singleDetail.cnapsCode));//收款方联行号
        tmpXElement.addChild(new XElement("currencyCode", p_req1908.singleDetail.payCur));//币别代码
        tmpXElement.addChild(new XElement("wishTime", p_req1908.singleDetail.payTime));//期望支付日期
        tmpXElement.addChild(new XElement("tradeMoney", p_req1908.singleDetail.payAmount));//支付金额
        tmpXElement.addChild(new XElement("urgentFlag", p_req1908.singleDetail.paySpd));//是否加急 0普通1加急
        if ("1".equals(p_req1908.singleDetail.isPrivate)) {
            tmpXElement.addChild(new XElement("privateFlag", "1"));//是否对私 0对公1对私
        } else {
            tmpXElement.addChild(new XElement("privateFlag", "0"));
        }
        if ("1".equals(p_req1908.singleDetail.sameCity)) {
            tmpXElement.addChild(new XElement("cityFlag", "0"));//同城异地 0同城1异地
        } else {
            tmpXElement.addChild(new XElement("cityFlag", "1"));
        }
        if ("1".equals(p_req1908.singleDetail.sameBnk)) {
            tmpXElement.addChild(new XElement("bankFlag", "0"));//同行跨行 0同行1跨行
        } else {
            tmpXElement.addChild(new XElement("bankFlag", "1"));
        }
        tmpXElement.addChild(new XElement("tradeMemo", p_req1908.singleDetail.purpose));//用途
        nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
        xmlWriter.writeXElement(tmpXElement);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndDocument();
        //发送银行前置
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
        //解析报文
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String retCode = tmpBkReader.getSimpleText("retCode");
                String respMsg = tmpBkReader.getSimpleText("retMsg").trim();
                String billCode = tmpBkReader.getSimpleText("billCode");
                if (isActiveRetCode(retCode) && !StringHelper.isNullOrEmpty(billCode)) {
                    retDetail.respCode = "0";
                    retDetail.respInfo = respMsg;
                    retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    retDetail.transState = retCode;
                    retDetail.payInfoCode = retCode;
                    //银行推送流水号处理：文件存储
                    retDetail.outTransID = billCode;
                    try {
                        createFile(p_req1908.singleDetail.askNumber, retDetail.outTransID);
                    } catch (IOException e) {
                        WriteBankLogLn("交易流水号" + p_req1908.singleDetail.askNumber + "保存银行返回付款单号失败：" + retDetail.outTransID + ",原因：" + e.toString());
                    }
                } else {
                    retDetail.respCode = "0";
                    retDetail.respInfo = respMsg;
                    retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    retDetail.transState = "fail+3";
                    retDetail.payInfoCode = "fail";
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpSbMsg.toString();
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    /**
     * 交易明细状态查询
     *
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        //返回ats对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        transCode = "DealQueryTransfer";
        seqNo = p_req1944.reqHeader.transSeqID;
        //读取银行流水号
        String filename = p_req1944.reqHeader.reqSeqID;
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        try {
            String orgSeqNo = read(bankFront.bkTransFolder + "\\" + filename + ".txt");
            //写报文
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("body");
            xmlWriter.writeStartElement("entity");
            xmlWriter.writeElementString("billCode", orgSeqNo);//交易流水号
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            //发送银行前置机
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            //赋值返回ats
            XmlTextReader tmpBkReader;
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String retCode = tmpBkReader.getSimpleText("retCode");
                    String respMsg = tmpBkReader.getSimpleText("retMsg").trim();
                    if (retCode != null && (isActiveRetCode(retCode) || "000001".equals(retCode) || "000002".equals(retCode))) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = respMsg;//处理说明
                        tmpRetDetail.reqSeqID = p_req1944.askNumber;
                        //交易状态: 000002-正在处理000000-成功 000001-失败
                        tmpRetDetail.transState = retCode;
                        tmpRetDetail.payInfoCode = tmpRetDetail.transState;

                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = respMsg;
                        tmpRetDetail.reqSeqID = p_req1944.askNumber;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.getMessage();
            WriteBankLogLn("查询状态失败：" + e.toString());
            e.printStackTrace();
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }

    private void createFile(String filename, String content) throws IOException {
        String path = bankFront.bkTransFolder + "\\" + filename + ".txt";
        File file = new File(path);
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        try {

            if (file.exists()) {
                throw new IOException(path + "文件已存在！");
            } else {
                File fileParent = file.getParentFile();
                if (!fileParent.exists()) {
                    fileParent.mkdirs();
                }
                boolean bool = file.createNewFile();
                if (file.exists() && bool) {
                    fos = new FileOutputStream(file);
                    osw = new OutputStreamWriter(fos, "GBK");
                    osw.write(content);
                } else {
                    throw new IOException("文件无法创建！");
                }
            }
        }catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (osw != null) {
                    osw.close();
                }
            }catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }

    private String read(String filePath) throws IOException {
        StringBuilder sb = new StringBuilder();
        FileInputStream fs = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {

                throw new IOException(filePath + "文件不存在！");
            }
            if (file.exists()) {
                fs = new FileInputStream(file);
                isr = new InputStreamReader(fs, "GBK");
                br = new BufferedReader(isr);

                String line = br.readLine();
                while (line != null) {
                    sb.append(line);
                    line = br.readLine();
                }
            } else {
                throw new IOException("文件读取失败！");
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fs != null) {
                fs.close();
            }
            if (isr != null) {
                isr.close();
            }
            if (br != null) {
                br.close();
            }
        }
        return sb.toString();
    }

}
